package net.esj.basic.core.view.tools;

import java.util.HashMap;
import java.util.Locale;
import java.util.Map;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.lang.StringUtils;

import net.esj.basic.core.engine.tools.crypt.Crypt;
import net.esj.basic.core.view.tools.searcher.Searcher;
import net.esj.basic.core.view.tools.searcher.SearcherColumn;
import net.esj.basic.core.view.tools.searcher.SearcherImpl;

public class ActionContext {

	public static final String HTTP_REQUEST = "net.melon.core.support.HttpServletRequest";

	public static final String HTTP_RESPONSE = "net.melon.core.support.HttpServletResponse";
	
	public static final String CRYPT_KEY = "net.melon.core.action.crypt";

	public static final String COOKIE_MAX_AGE_KEY = "net.melon.core.action.cookieMaxAge";
	
	public static final String LOCALE = "net.melon.core.ActionContext.locale";
	
	static ThreadLocal context = new ThreadLocal();
	
	Map<String, Object> map = new HashMap<String, Object>() ;
	
	public static long default_cookieMaxAge = 1000 * 60 * 60 * 24 * 14;//默认2周
	
	public Object get(String key) {
        return map.get(key);
    }
	
	public void put(String key, Object value) {
		map.put(key, value);
    }
	
	public static ActionContext getContext() {
		return (ActionContext) context.get();
	}

	public static void setContext(ActionContext actContext) {
		context.set(actContext);
	}
	
	public static void setRequest(HttpServletRequest request) {
        getContext().put(HTTP_REQUEST, request);
    }
	
	public static void setResponse(HttpServletResponse response) {
        getContext().put(HTTP_RESPONSE, response);
    }
	
	public static void setCrypt(Crypt crypt) {
		getContext().put(CRYPT_KEY, crypt);
	}
	
	public static void setCookieMaxAge(long cookieMaxAge) {
		getContext().put(COOKIE_MAX_AGE_KEY, cookieMaxAge);
	}
	
	public static void setLocale(Locale locale) {
        getContext().put(LOCALE, locale);
    }

    public static Locale getLocale() {
        Locale locale = (Locale) getContext().get(LOCALE);

        if (locale == null) {
            locale = Locale.getDefault();
            setLocale(locale);
        }

        return locale;
    }
    
	/**********************************************************/
	
	public static ClientAgent getClient() {
		return new ClientAgent((HttpServletRequest) getRequest());
	}

	public static long getCookieMaxAge() {
		return (Long) getContext().get(COOKIE_MAX_AGE_KEY);
	}
	
	public static ServletRequest getRequest() {
		return (HttpServletRequest) getContext().get(HTTP_REQUEST);
	}

	public static ServletResponse getResponse() {
		return (HttpServletResponse) getContext().get(HTTP_RESPONSE);
	}
	
	public static Crypt getCrypt(){
		return (Crypt) getContext().get(CRYPT_KEY);
	}

	public static Searcher getSearcher(String key){
		Map<String,Searcher> searchers = (Map<String, Searcher>) getSession().getAttribute(Searcher.REQUEST_SEARCH_KEY);
		if(searchers==null){
			searchers = new HashMap<String, Searcher>();
			getSession().setAttribute(Searcher.REQUEST_SEARCH_KEY, searchers);
		}
		Searcher searcher =searchers.get(key);
		if(searcher==null){
			searcher = new SearcherImpl(key);
			searchers.put(key, searcher);
		}
		return searcher;
	}
	
	public static void clearAllSearchers() {
		Map<String,Searcher> searchers = (Map<String, Searcher>) getSession().getAttribute(Searcher.REQUEST_SEARCH_KEY);
		if(searchers==null){
			return;
		}
		searchers.clear();
	}

	public static void clearSearcher(String key) {
		Map<String,Searcher> searchers = (Map<String, Searcher>) getSession().getAttribute(Searcher.REQUEST_SEARCH_KEY);
		if(searchers==null){
			return;
		}
		searchers.remove(key);
	}
	
	public static void addSearchColumn(String searcherKey, String key, String type,String view,
			Object value) {
		Searcher searcher = getSearcher(searcherKey);
		searcher.newColumn(key, view,type, value);
	}
	
	public static void addSearchColumn(String searcherKey, SearcherColumn column) {
		Searcher searcher = getSearcher(searcherKey);
		searcher.newColumn(column);
	}
	
	public static void addSearchOrder(String searcherKey, String key, String view,
			Object value, int order) {
		Searcher searcher = getSearcher(searcherKey);
		searcher.newOrderBy(key, view, value,order);
	}

	public static void addSearchOrder(String searcherKey, SearcherColumn column,
			int order) {
		Searcher searcher = getSearcher(searcherKey);
		searcher.newOrderBy(column,order);
	}

	public static void addSearchOrder(String searcherKey, String key, String view,
			Object value) {
		Searcher searcher = getSearcher(searcherKey);
		searcher.newOrderBy(key, view, value);
	}

	public static void addSearchOrder(String searcherKey, SearcherColumn column) {
		Searcher searcher = getSearcher(searcherKey);
		searcher.newOrderBy(column);
	}

	public static void clearSearchOrder(String searcherKey) {
		Searcher searcher = getSearcher(searcherKey);
		searcher.clearOrderAll();
	}

	public static HttpSession getSession() {
		return ((HttpServletRequest) getRequest()).getSession();
	}

	public static void addRequestAttribute(String key, Object o) {
		getRequest().setAttribute(key, o);
	}

	public static void addSessionAttribute(String key, Object o) {
		getSession().setAttribute(key, o);
	}

	public static void addCookie(Cookie cookie) {
		cookie.setMaxAge((int) getCookieMaxAge());
		((HttpServletResponse)getResponse()).addCookie(cookie);
	}

	public static void addCookie(String key, String value,boolean needEncrypt) {
		if(needEncrypt && getCrypt()!=null){
			value = getCrypt().encrypt(value);
		}
		Cookie cookie  = new Cookie(key, value);
		cookie.setMaxAge((int) getCookieMaxAge());
		((HttpServletResponse)getResponse()).addCookie(cookie);
	}
	
	public static void addCookie(String key, String value,int maxAge,boolean needEncrypt) {
		if(needEncrypt && getCrypt()!=null){
			value = getCrypt().encrypt(value);
		}
		Cookie cookie  = new Cookie(key, value);
		cookie.setMaxAge(maxAge);
		//System.out.println("JSESSIONID ON ADD COOKIE ="+((HttpServletRequest)getRequest()).getSession().getId());
		((HttpServletResponse)getResponse()).addCookie(cookie);
	}
	
	public static void clearCookie(String name){
		//System.out.println("JSESSIONID ON CLEAR COOKIE ="+((HttpServletRequest)getRequest()).getSession().getId());
		if(((HttpServletRequest) getRequest()).getCookies()==null){
			return;
		}
		for(Cookie co:((HttpServletRequest) getRequest()).getCookies()){
			if(StringUtils.equals(co.getName(), name)){
				co.setValue("");
				((HttpServletResponse) getResponse()).addCookie(co);
			}
		}
	}

	public static String getCookieValue(String key, boolean needDecrypt) {
		Cookie[] cookies = ((HttpServletRequest)getRequest()).getCookies();
		if(cookies!=null){
			for (int i = 0; i < cookies.length; i++) {
				Cookie c = cookies[i];  
				if(c.getName().equalsIgnoreCase(key)){
					if(needDecrypt && getCrypt()!=null){
						return getCrypt().decrypt(c.getValue());
					}else{
						return c.getValue();
					}
				}
			}
		}
		return null;
	}


}
